// 中间人
// 回头发布者要发布新的消息，就会通知中间人，中间人再通知所有订阅者
// 并且订阅者的列表也是由中间人维护的
import { ISubscriber, IBroker } from "./Interface";

// 中间人要做的事情：
// 1. 帮发布者发布消息
// 2. 帮订阅者订阅主题消息
export class Broker implements IBroker {
  // 内部维护一个主题和订阅者的列表
  private topics: Map<string, ISubscriber[]> = new Map();

  // 订阅方法
  subscribe(topic: string, subscriber: ISubscriber): void {
    // 拿到对应的主题的观察者列表（订阅者列表）
    const subTopicSubscribers = this.topics.get(topic) || [];
    subTopicSubscribers.push(subscriber);
    this.topics.set(topic, subTopicSubscribers);
  }

  // 取消订阅方法
  unsubscribe(topic: string, subscriber: ISubscriber): void {
    const subTopicSubscribers = this.topics.get(topic) || [];
    const index = subTopicSubscribers.indexOf(subscriber);
    if (index !== -1) {
      subTopicSubscribers.splice(index, 1);
    }
  }

  // 发布消息方法
  publish(topic: string, message: any): void {
    // 获取到订阅了这个主题的订阅者列表
    const subTopicSubscribers = this.topics.get(topic) || [];
    // 遍历所有的订阅者，通知他们
    for (const subscriber of subTopicSubscribers) {
      subscriber.receive(message);
    }
  }
}
